home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SPACE 2
/
SPACE - Library 2 - Volume 1.iso
/
music
/
87
/
c
/
clines.c
< prev
next >
Wrap
C/C++ Source or Header
|
1986-12-19
|
32KB
|
813 lines
/********************************************************************/
/* C_LINES.C */
/********************************************************************/
/* 1986 by David Archibald. CIS 73256,2640 */
/* Released to the public domain on Dec. 6, 1986. */
/* */
/* This program is compatible with both Alcyon and Megamax. */
/*------------------------------------------------------------------*/
/* This program adds line numbers to a C text file, and then sends */
/* the file to the screen, printer or a disk file. */
/* */
/*------------------------------------------------------------------*/
/* The command line reads: */
/* A:inputFile [B:outputFile] [-a] [-s] [-p] [-h] [-f {xx}] */
/* [-t {x}] [-c] [-b {xxxxx}] */
/*------------------------------------------------------------------*/
/* All of the commands, and any numbers that follow them, must be */
/* separated on the command line by a space. All the commands that */
/* are inclosed by brackets, are optional. */
/*------------------------------------------------------------------*/
/* inputFile - is the C text file name. It must be the 1st command */
/* on the command line. */
/* */
/* outputFile - is the file name that the output from the -a and -s */
/* is sent to. A file name is required with either of */
/* these commands, and it must be the 1st item */
/* following the inputFile name, on the command line. */
/*__________________________________________________________________*/
/* the use of a RAM disk with these two commands, is *highly* */
/* recommended. */
/*------------------------------------------------------------------*/
/* -a - adds line numbers to each line, and then save it to */
/* the outputFile. */
/* */
/* -s - strips the line numbers from a inputFile that was */
/* previously created, by using the '-a' command. */
/*------------------------------------------------------------------*/
/* All of the following commands are ignored, when the -a or -s */
/* commands are chosen. */
/*------------------------------------------------------------------*/
/* These two commands work with both screen or printer output. */
/*------------------------------------------------------------------*/
/* */
/* -c - truncates the output line whenever it's length */
/* exceeds 80 characters (counting the line number). */
/* This command works with both screen or printer output*/
/* */
/* -b - skips 'x' amount of inputFile's lines. Does not print*/
/* any lines, until the line number that follows -b on */
/* the command is reached. This command does not have */
/* default line number. If no line number is entered, */
/* then the program will begin printing at line 1. */
/*------------------------------------------------------------------*/
/* */
/* -p - sends the text file to the printer. If a wrap-around */
/* occurs, the text on the 2nd line is indented, so */
/* that it starts on the same column as the 1st line */
/* (it takes into account the line number). */
/* */
/*------------------------------------------------------------------*/
/* the following commands are ignored, unless the output is sent */
/* to the printer. */
/*------------------------------------------------------------------*/
/* */
/* -h - sends a header to the printer. The header consists */
/* of 6 lines. The 1st two are blank, the 3rd is the */
/* name of the file being listed, the 4th is the page */
/* number and the time (24 hour clock) & date of */
/* printing, and the 5th and 6th are blank. */
/* */
/* -f - prints 'x' amount of blank lines at the bottom of the*/
/* page to skip over the perf. The the number of blank */
/* lines is entered on the command line, after the -f */
/* command. The maximum number is 6 lines. If there is */
/* no number, then the footer defaults to 3 lines. */
/* */
/* -t - Tabs the printout over a user defined amount of */
/* up to 15 spaces. If no number follows the -t command,*/
/* then the tab defaults to 6 spaces. */
/* */
/*------------------------------------------------------------------*/
/* If you enter only a input file name, the defaults are: */
/* */
/* output to the screen, no header, no tab, no truncate, no footer, */
/* and start output at line number 1. */
/*------------------------------------------------------------------*/
/* These commands work whether the file is going to the, disk */
/* printer or screen: */
/* pressing 'Q' exits the program. */
/* pressing 'p' pauses the program, and */
/* any other key restarts it. */
/* */
/********************************************************************/
/* I M P O R T A N T N O T E ! ! ! ! */
/* */
/* If you are going to compile this program with Alcyon, you must */
/* enlarge the STACK size in the "Gemstart" link file, otherwise */
/* the stack will overflow and start to overwrite the programs */
/* variables (I changed the stack size from 1K to 3K). If you are */
/* using Megamax, just ignore this. */
/********************************************************************/
#include <stdio.h>
#include <osbind.h>
#include <string.h>
#define EMPTY 0
#define CONT 1
#define QUIT 0
#define ON 1
#define TOLOWER(c) ((c)>='A' && (c)<='Z' ? (c)+=32:(c))
/* Alcyon doesn't have this and we need it with Megamax. */
typedef int VOID; /* needed only with Megamax */
struct cm {
int strip;
int add;
int print;
int header;
int footer;
int foot_amt;
int tab;
int tab_amt;
int line_num;
int prt_cnt;
int page_no;
int trun;
int begin;
int start_ln;
};
/* ------------global variables: for input & output files------------ */
FILE *fp_in;
FILE *fp_out;
FILE *fopen(); /* needed only with Alcyon */
main (argc,argv)
int argc;
char *argv[];
{
int flag=CONT, t, esc=0x011b;
char str_in[255];
static struct cm command={0};
Cconout(esc); /* turn cursor off (it looks better*/
Cconout('f'); /* when outputing with it off.) */
Cconout(esc); /* clear the screen. */
Cconout('E');
parse_cmd(argv,&command,argc); /* get commands entered */
flag=open_input(argv,argc); /* open input C file */
if ((command.add==ON || command.strip==ON) && flag==CONT)
flag=open_out(argv); /* open output file */
while(flag==CONT)
{
flag=keypress(); /* check for keypress */
if (flag==QUIT) break;
/*____________________________________________________________________*/
/* read line from input file. flag=0 if EOF reached. */
/*--------------------------------------------------------------------*/
flag=get_str(str_in);
/*____________________________________________________________________*/
/* after the last line has been read, wait for keypress before */
/* returning to the desktop or the command mode. */
/*--------------------------------------------------------------------*/
if (flag==QUIT)
{
pause(); /* wait until key is pressed */
break;
}
/*____________________________________________________________________*/
/* if you don't want to start at the 1st line in the file then loop */
/* until the line number that was entered is reached. */
/*--------------------------------------------------------------------*/
if (command.begin==ON && command.line_num+1<command.start_ln)
{
skip_lines(&command);
continue; /* skip other commands. */
}
/*____________________________________________________________________*/
/* strip line number off input line & write to output file */
/*--------------------------------------------------------------------*/
else if (command.strip==ON)
{
strip_num(str_in);
continue; /* skip other commands. */
}
/*____________________________________________________________________*/
/* add line number to line & write to output file */
/*--------------------------------------------------------------------*/
else if (command.add==ON)
{
add_num(str_in, &command);
continue; /* once again--don't check for cmd */
}
/*____________________________________________________________________*/
/* send line to printer */
/*--------------------------------------------------------------------*/
else if (command.print==ON)
flag=printer(str_in, &command, argv);
/*____________________________________________________________________*/
/* or send line to screen */
/*--------------------------------------------------------------------*/
else flag=prt_crt(str_in, &command);
}
Cconout(esc); /* turn cursor back on. */
Cconout('e');
if (fp_in!=0) fclose(fp_in);
if (fp_out!=0) fclose(fp_out);
}
VOID parse_cmd(cmd_line, c, num)
char *cmd_line[];
struct cm *c;
int num;
{
int t, amt;
for (t=2;t<num;++t) /* loop 'til all commands checked */
{
if (cmd_line[t][0]!='-') /* don't treat 2nd file name */
continue; /* as command, check for '-'.*/
switch(TOLOWER(cmd_line[t][1])) /* if the command is upper-*/
{ /* case then make it lower.*/
case 's':
c->strip=ON; /* strip line #'s from input file */
return(EMPTY); /* ignore all other commands */
case 'a':
c->add=ON; /* add line #'s to input file */
return(EMPTY); /* ignore all other commands */
case 'p':
c->print=ON; /* send output to the printer */
break; /* check for next command */
case 'c':
c->trun=ON; /* truncate output to screen */
break; /* or prt past 80 characters. */
case 'h':
c->header=ON; /* print header to printer */
break; /* check for next command */
case 'f':
c->footer=ON; /* print footer to printer */
/*____________________________________________________________________*/
/* check if the size of footer follows command */
/*--------------------------------------------------------------------*/
c->foot_amt=3; /* incase no size entered = default */
if (t+1<num)
{
amt=atoi(cmd_line[t+1]); /* get number after '-f' */
if (amt<0 || amt>6) /* make it fall in range */
amt=6;
if (amt!=0)
{
c->foot_amt=amt; /* if all ok, then equal input */
++t; /* move loop pointer past # */
}
}
break; /* check for next command. */
case 'b':
c->begin=ON; /* skip lines. */
/*____________________________________________________________________*/
/* check for the line number to skip to */
/*--------------------------------------------------------------------*/
if (t+1<num)
{
amt=atoi(cmd_line[t+1]); /* get number after '-b' */
if (amt<0) /* make it fall in range */
amt=0; /* <0 then don't skip any. */
if (amt!=0)
{
c->start_ln=amt; /* if all ok, then equal input */
++t; /* move loop pointer past # */
}
}
break; /* check for next command. */
case 't':
c->tab=ON; /* tab to printer */
/*____________________________________________________________________*/
/* check if size of tab follows command */
/*--------------------------------------------------------------------*/
c->tab_amt=6; /* incase no size entered = default */
if (t+1<num)
{
amt=atoi(cmd_line[t+1]); /* get number after '-t'. */
if (amt<0 || amt>15) /* make it fall in range */
amt=15;
if (amt!=0)
{
c->tab_amt=amt; /* if all ok, equal input */
++t; /* move loop pointer past # */
}
}
}
}
}
keypress()
{
char ch;
if (Cconis()<0) /* is there a character available? */
{
ch=Cnecin();
if (ch=='p' || ch=='P') /* pause listing? */
ch=Cnecin(); /* wait for keypress */
if (ch=='q' || ch=='Q') return(QUIT); /* quit the program */
}
return(CONT);
}
open_input(cmd_line,num)
int num;
char *cmd_line[];
{
if (num>2 && cmd_line[2][0]!='-') /* are there 2 names for */
/* strcmp to check. */
if (strcmp(cmd_line[1],cmd_line[2])==0) /* check if input & */
{ /* output name are the same.*/
printf("\n\nWHOA! both the input and");
printf(" the output names are the same: %s\n",cmd_line[1]);
pause();
return(QUIT); /* exit the program.*/
}
fp_in=fopen(cmd_line[1],"r");
if (fp_in==0)
{
printf("\nCannot open input file: %s \n",cmd_line[1]);
pause();
return(QUIT); /* set flag to 0 on return & exit prg. */
}
return(CONT);
}
open_out(cmd_line)
char *cmd_line[];
{
if (cmd_line[2][0]!='-') /* don't use a command as */
fp_out=fopen(cmd_line[2],"w"); /* the 2nd file name. */
if (fp_out==0)
{
printf("\nCannot open output file: %s \n",cmd_line[2]);
pause();
return(QUIT); /* set 'flag' to 0 on return & exit program */
}
return(CONT);
}
get_str(line)
char line[];
{
fgets(line,255,fp_in); /* read line from input file */
if (line[0]=='\0')
return(QUIT); /* when EOF then all done */
else return(CONT);
}
/*____________________________________________________________________*/
/* save input line back to output file minus */
/* the line number at the start of line. */
/*--------------------------------------------------------------------*/
VOID strip_num(line)
char line[];
{
int esc=0x011b;
/*____________________________________________________________________*/
/* check for line number at the start of the line-- incase a */
/* new line was added to the file after the line numbers were added. */
/*--------------------------------------------------------------------*/
if (atoi(line)==0)
{
fputs(line,fp_out); /* if no line # then output the line*/
return(EMPTY); /* without striping non-existent #. */
}
fputs(&line[8],fp_out); /* output line. */
Cconout(esc); /* home the cursor. */
Cconout('H');
printf("\n\nStriping line number: %d\n",atoi(line));
}
/*____________________________________________________________________*/
/* save input line to output file with line */
/* numbers at the start of the line. */
/*format of line is: 1 space, up to 5 numbers, 2 spaces, and the line.*/
/*--------------------------------------------------------------------*/
VOID add_num(line,c)
char line[];
struct cm *c;
{
int esc=0x011b;
++c->line_num;
fprintf(fp_out,"%5d %s",c->line_num,line);
Cconout(esc); /* home the cursor. */
Cconout('H');
printf("\n\nadding line number: %d\n",c->line_num);
}
printer(line,c,cmd_line)
char line[], *cmd_line[];
struct cm *c;
{
static int been_here=0;
static char date[3][3], time[3][3];
int t, t2, line_len, length, status, h_f_flag=0;
char ch, num[9];
/* the follow code checks if the printer is ready and gets the time & */
/* date. It is only executed the 1st time this routine is called. */
if (been_here==0)
{
++been_here; /* pass this way never more */
do
{
status=Cprnos(); /* is printer ready? status=1 if yes */
if (status==0)
{
printf("\n\nPrinter is not ready. Press any key to ");
printf("continue (Q to quit)\n");
ch=Cnecin();
if (ch=='q' || ch=='Q')
return(QUIT); /* all done! exit program. */
}
}
while (status==0); /* loop until printer is on or 'q' is entered*/
time_date(date,time); /* get time & date */
}
/********************* end of one pass only code. *********************/
h_f_flag=head_foot(c,cmd_line,date,time);
/* check if time to print the header or footer */
/*____________________________________________________________________*/
/* if the tab flag is on then space the line over tab_amt to that col.*/
/*--------------------------------------------------------------------*/
if (c->tab==ON)
for (t=0;c->tab_amt != t;++t)
Cprnout(' ');
/************************ end of tab section **************************/
/*____________________________________________________________________*/
/* let the horns sound! we finally print the line. well, almost... */
/* first print the line number. */
/*--------------------------------------------------------------------*/
sprintf(num,"%5d ",++c->line_num); /* convert to ASCII.*/
for (t=0;num[t]!='\0';++t)
Cprnout(num[t]); /* print line number. */
/*------------- now find out if the line will wrap around.------------*/
line_len=79-(c->tab_amt+8); /* 79 line size, 8=line # + 2 space*/
if (strlen(line)>line_len)
{
for (t=0;t != line_len && line[t]!='\0';++t)
Cprnout(line[t]); /* stop printing after */
/* reaching end of printer */
/* line. */
/*____________________________________________________________________*/
/* call head_foot before printing the 2nd line so if a header or */
/* is due to be printed, they will be. this way the header and footer */
/* are kept in their correct place (i.e. not printed 1 line to late).*/
/*--------------------------------------------------------------------*/
if (line[t]!='\0' && c->trun!=ON) /* if not end-of-line and*/
{ /* truncate isn't 'on'...*/
h_f_flag=head_foot(c,cmd_line,date,time);
if (h_f_flag!=0) /* was head or foot performed? */
Cprnout('\n'); /* if no - CR to 2nd line. */
for (t2=c->tab_amt+9;t2!= 0;--t2) /* tab for wrap- */
Cprnout(' '); /* around 2nd line. */
/* tab amt + 9 for line #. */
for (;line[t]!='\0';++t)
Cprnout(line[t]); /* print the rest of the line*/
}
else Cprnout('\n'); /* truncate the line. */
}
else for (t=0;line[t]!='\0';++t) /* if no wrap-around then */
Cprnout(line[t]); /* print the whole line. */
return(CONT);
}
/**********************************************************************/
/* TIME and DATE */
/**********************************************************************/
/* this routine load the system time and date and converts it into */
/* ASCII characters. these characters are returned to the calling */
/* routine in 2 arrays format so: time[3][3], date[3][3]. */
/* ( "\0" goes in the 3rd cell of the array.) */
/* */
/* hours will be in: time[0][0], time[0][1] */
/* minutes in : time[1][0], time[1][1] */
/* seconds in : time[2][0], time[2][1] */
/* */
/* month will be in: date[0][0], date[0][1] */
/* day in : date[1][0], date[1][1] */
/* year in : date[2][0], date[2][1] */
/**********************************************************************/
VOID time_date(date,time)
char date[][3], time[][3];
{
unsigned int work, date_time;
int t;
/* get date */
date_time=Tgetdate();
work=date_time & 31; /* mask all but lower 5 bits (day) */
sprintf(&date[1][0],"%d",work);
work=(date_time & 480)>>5; /* mask all but bits 5-8 (month) */
sprintf(&date[0][0],"%d",work);
work=(((date_time & 65024)>>9)+80);
/* mask all but bits 9-15 (year+80)*/
sprintf(&date[2][0],"%d",work);
/* get time */
date_time=Tgettime();
work=(date_time & 31)*2; /* mask bits 0=4 (seconds * 2) */
sprintf(&time[2][0],"%02d",work);
work=(date_time & 2016)>>5; /* mask bits 5-10 (minutes) */
sprintf(&time[1][0],"%02d",work);
work=(date_time & 63488)>>11; /* mask bits 11-15 (hour) */
sprintf(&time[0][0],"%02d",work);
}
prt_crt(line,c)
char line[];
struct cm *c;
{
int esc=0x011b;
char ch;
static int no_pause;
/*____________________________________________________________________*/
/* if 23 lines have been printed to the screen then wait for */
/* keypress to continue. */
/*--------------------------------------------------------------------*/
if (++c->prt_cnt==23 && no_pause!=ON)
{
c->prt_cnt=0;
printf("Press any key to continue (Q to quit--");
printf("N to cancel this prompt line).\n");
ch=Cnecin();
if (ch=='q' || ch=='Q') return(QUIT);
if (ch=='n' || ch=='N') no_pause=ON;
}
++c->line_num; /* inc line number counter */
Cconout(esc); /* turn on end of line wrap */
Cconout('v');
if (c->trun==ON && strlen(line) > 74) /* if truncate is 'on'*/
printf("%5d %.73s\n",c->line_num,line);
else
printf("%5d %s",c->line_num,line); /* or print it all. */
return(CONT);
}
VOID pause()
{
char ch;
Cconws("\n All done. Press any key to exit.");
ch=Cnecin();
}
head_foot(c,cmd_line,date,time)
char date[][3],time[][3], *cmd_line[];
struct cm *c;
{
static char page[]="page ", head_line[]=" Printed on: ";
int t, name_len, h_f_flag=0;
char ch, num[9], colon_slash;
++c->prt_cnt; /* keep track of what line the printer is on */
/*____________________________________________________________________*/
/* if skip over perf flag is on and the printers line cnt=66 - DO IT! */
/*--------------------------------------------------------------------*/
if (c->prt_cnt+c->foot_amt==67 && c->footer==ON)
{
for (t=c->foot_amt;t != 0;--t,++c->prt_cnt)
Cprnout('\n');
h_f_flag=ON; /* signal that footer was performed. */
}
/************************ end of footer section ***********************/
if (c->prt_cnt>=66)
c->prt_cnt=ON; /* re-set line counter */
/*____________________________________________________________________*/
/* if header flag is on and the printers line cnt=1 then print header */
/*--------------------------------------------------------------------*/
if (c->prt_cnt==1 && c->header==ON)
{
h_f_flag=ON; /* signal that header was performed. */
Cprnout('\n'); /* print 2 blank lines */
Cprnout('\n');
/*____________________________________________________________________*/
/* to center the input file's name on the 3rd line 1st get its length */
/* then subtract it from 80 and then divide the remainder by 2. print */
/* this number of spaces to the printer and then the file name. */
/* Voila'! centered print. */
/*--------------------------------------------------------------------*/
name_len=strlen(cmd_line[1]); /* get len of file's name */
name_len=80-name_len;
if (name_len>0) /* if > 0 then file name */
name_len /= 2; /* is < 80 char. in length*/
else /* if < 0 then it's > 80 */
{ /* so don't try to center */
name_len=0; /* it because it'll use 2 */
c->prt_cnt+=1; /* lines anyways. (how you*/
} /* will get 80 or more characters */
/* on the cmd line, I do not know!*/
/* but then you never know, so... */
for (;name_len != 0;--name_len)
Cprnout(' ');
for (t=0;cmd_line[1][t]!='\0';++t) /* print file name */
Cprnout(cmd_line[1][t]);
Cprnout('\n');
/*____________________________________________________________________*/
/* print time, date and page number and then 2 blank lines. */
/*--------------------------------------------------------------------*/
for (t=0;head_line[t]!='\0';++t)
Cprnout(head_line[t]); /* print 'Printed on:' */
colon_slash='/';
prt_t_d(date,colon_slash); /* print date with slash */
Cprnout(' ');
colon_slash=':';
prt_t_d(time,colon_slash); /* print time with colon */
for (t=0;t != 26;++t) /* print 26 spaces before*/
Cprnout(' '); /* printing page number. */
for (t=0;page[t]!='\0';++t)
Cprnout(page[t]); /* print 'page' */
sprintf(num,"%d",++c->page_no); /* convert int to ASCII */
for (t=0;num[t]!='\0';++t)
Cprnout(num[t]); /* print page number. */
for (t=0;t!=3;++t) /* header takes up 6 lines.*/
Cprnout('\n'); /* print 2 blank lines. */
c->prt_cnt+=6; /* update prn line cnt. */
}
return(h_f_flag);
}
/*____________________________________________________________________*/
/* prints the time and date to the printer */
/* on entry 'colon_slash' equals a '/' when printing the date. it */
/* separates the mm/dd/yy. 'colon_slash' equals a ':' when printing */
/* the date. it separates the hh:mm:ss. */
/*--------------------------------------------------------------------*/
VOID prt_t_d(td,colon_slash)
char td[][3],colon_slash;
{
int t, t2;
char ch=' ';
for (t=0;t!=3;++t)
{ /* print a space on the 1st pass */
Cprnout(ch); /* so we don't get something */
ch=colon_slash; /* like /mm/dd/yy or :hh:mm:ss*/
for (t2=0;t2!=3;++t2)
Cprnout(td[t][t2]);
}
}
VOID skip_lines(c)
struct cm *c;
{
int esc=0x011b;
++c->line_num;
Cconout(esc); /* home the cursor. */
Cconout('H');
printf("\n\nreading line number: %d",c->line_num);
printf(" but waiting for line: %d\n",c->start_ln);
}